//
//  CommonEmitterView.m
//  AnimationDemo
//
//  Created by Jiaozl 2018 on 2018/9/14.
//  Copyright © 2018年 Jiaozl. All rights reserved.
//

#import "CommonEmitterView.h"

@implementation CommonEmitterView

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    
//    [self redpacketRain];
    
    
}

#pragma mark - 红包雨
- (CAEmitterLayer *)redpacketLayer {
    if(_redpacketLayer==nil) {
        [self setClipsToBounds:true]; /// 不设置这个，红包可以在本视图区域外显示

        // 1. 设置CAEmitterLayer
        _redpacketLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.bounds.size.width*0.5, -10)
                                                      size:CGSizeMake(self.bounds.size.width, 100)
                                               emitterMode:kCAEmitterLayerSurface
                                              emitterShape:kCAEmitterLayerLine
                                                renderMode:kCAEmitterLayerUnordered];
        [self.layer addSublayer:_redpacketLayer];
        
        // 每秒产生粒子数量的系数
        _redpacketLayer.birthRate = 0.0f;
    
        // 2. 配置cell
        CAEmitterCell *redpacketCell = [self ZLEmitterCellContents:(__bridge id)[UIImage imageNamed:@"red_paceket"].CGImage
                                                         birthRate:3.0f lifetime:3.0f
                                                          velocity:8.0f
                                                             scale:0.5];
        // 粒子在y方向的加速度
        redpacketCell.yAcceleration = 1000.f;
    
    
        // 3. 粒子添加到EmitterLayer上
        _redpacketLayer.emitterCells = @[redpacketCell];
    }
    return _redpacketLayer;
}


#pragma mark - 下雨
- (CAEmitterLayer *) rainLayer {
    if (_rainLayer==nil) {
    
        // 1. 设置CAEmitterLayer
        // position.y最好不要设置为0 最好<0
        _rainLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.bounds.size.width * 0.5, -10)
                                                 size:self.frame.size
                                          emitterMode:kCAEmitterLayerSurface
                                         emitterShape:kCAEmitterLayerLine
                                           renderMode:nil];
        [self.layer addSublayer:_rainLayer];
    
        // 2. 配置cell
        CAEmitterCell *snowCell = [self ZLEmitterCellContents:(id)[[UIImage imageNamed:@"rain_white"] CGImage]
                                                    birthRate:25.f lifetime:20.f
                                                     velocity:10.f
                                                        scale:0.1];
    
        snowCell.speed = 10.f;
        
        snowCell.velocityRange = 10.f;
        snowCell.yAcceleration = 1000.f;
        
        snowCell.scaleRange = 0.f;
        
        // 3.添加到图层上
        _rainLayer.emitterCells = @[snowCell];
    }
    return _rainLayer;
}

#pragma mark - 下雪
- (CAEmitterLayer *)snowLayer {
    if (_snowLayer == nil) {
        // 1. 设置CAEmitterLayer
        _snowLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.bounds.size.width * 0.5, -10) size:self.frame.size emitterMode:kCAEmitterLayerSurface emitterShape:kCAEmitterLayerLine renderMode:nil];
        [self.layer addSublayer:_snowLayer];
        
        // 2. 配置cell
        CAEmitterCell * snowCell = [self ZLEmitterCellContents:(id)[[UIImage imageNamed:@"snow_white"] CGImage]
                                                     birthRate:10.f lifetime:200.f
                                                      velocity:1.f
                                                         scale:0.2];

        snowCell.speed = 1.f; // 可以与birthRate搭配使用
        
        snowCell.velocityRange = 10.f;
        snowCell.yAcceleration = 10.f;
        
        snowCell.scaleRange = 0.3f;
        
        snowCell.emissionLongitude = M_PI_2; // 向下
        snowCell.emissionRange = M_PI_4; // 向下
        
        // 3.添加到图层上
        _snowLayer.emitterCells = @[snowCell];
    }
    return _snowLayer;
}


#pragma mark - 五彩小球
- (CAEmitterLayer *)colorBallLayer {
    if (_colorBallLayer==nil) {
        
        // 1. 设置CAEmitterLayer
        _colorBallLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.layer.bounds.size.width, 0.f) size:self.frame.size emitterMode:kCAEmitterLayerPoints emitterShape:kCAEmitterLayerPoint renderMode:nil];
        [self.layer addSublayer:_colorBallLayer];
        
        // 2. 配置CAEmitterCell
        CAEmitterCell * colorBallCell = [CAEmitterCell emitterCell];
        colorBallCell.name = @"colorBallCell";
        
        colorBallCell.birthRate = 20.f;
        colorBallCell.lifetime = 10.f;
        
        colorBallCell.velocity = 40.f;
        colorBallCell.velocityRange = 100.f;
        colorBallCell.yAcceleration = 15.f;
        
        colorBallCell.emissionLongitude = M_PI; // 向左
        colorBallCell.emissionRange = M_PI_4; // 围绕X轴向左90度
        
        colorBallCell.scale = 0.2;
        colorBallCell.scaleRange = 0.1;
        colorBallCell.scaleSpeed = 0.02;
        
        colorBallCell.contents = (id)[[UIImage imageNamed:@"circle_white"] CGImage];
        colorBallCell.color = [[UIColor colorWithRed:0.5 green:0.f blue:0.5 alpha:1.f] CGColor];
        colorBallCell.redRange = 1.f;
        colorBallCell.greenRange = 1.f;
        colorBallCell.blueSpeed = 1.f;
        colorBallCell.alphaRange = 0.8;
        colorBallCell.alphaSpeed = -0.1f;
        
        // 添加
        _colorBallLayer.emitterCells = @[colorBallCell];
    }
    return _colorBallLayer;
}

/**
 * 移动发射源到某个点上
 */
- (void)setBallInPsition:(CGPoint)position{
    
    CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"emitterCells.colorBallCell.scale"];
    anim.fromValue = @0.2f;
    anim.toValue = @0.5f;
    anim.duration = 1.f;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    
    // 用事务包装隐式动画
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    [self.colorBallLayer addAnimation:anim forKey:nil];
    [self.colorBallLayer setValue:[NSValue valueWithCGPoint:position] forKeyPath:@"emitterPosition"];
    [CATransaction commit];
}
#pragma mark - 爱心
- (CAEmitterLayer *)heartLayer {
    if (_heartLayer == nil) {
        
        // 1.CAEmitterLayer
        _heartLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height - 20) size:CGSizeMake(100, 30)
                                           emitterMode:kCAEmitterLayerVolume
                                          emitterShape:kCAEmitterLayerRectangle
                                            renderMode:kCAEmitterLayerAdditive];
        [self.layer addSublayer:_heartLayer];
        
        
        // 2.配置CAEmitterCell
        CAEmitterCell * heartCell = [CAEmitterCell emitterCell];
        heartCell.name = @"heartCell";
        
        heartCell.birthRate = 0.f;
        heartCell.lifetime = 10.f;
        
        heartCell.velocity = -120.f;
        heartCell.velocityRange = 60.f;
        heartCell.yAcceleration = 20.f;
        
        heartCell.emissionLongitude = M_PI * 0.5;
        heartCell.emissionRange = M_PI_2 * 0.55;
        
        heartCell.contents = (id)[[UIImage imageNamed:@"love_red"]CGImage];
        heartCell.color = [[UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:0.5] CGColor];
        heartCell.redRange = 0.3;
        heartCell.blueRange = 0.3;
        heartCell.alphaRange = -0.5/heartCell.lifetime;
        
        heartCell.scale = 0.5;
        heartCell.scaleRange = 0.5;
        heartCell.spinRange = 2.0 * M_PI;  // 自转
        
        // 添加动画
        _heartLayer.emitterCells = @[heartCell];
    }
    return _heartLayer;
}

#pragma mark - 火焰
- (void)fireAndSmoke {
    // 直接在smokelayer中添加了firelayer
}
- (CAEmitterLayer *)fireLayer {
    if (_fireLayer==nil) {
        // 火花
        
        _fireLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height - 60) size:CGSizeMake(50.0, 0)
                                          emitterMode:kCAEmitterLayerOutline
                                         emitterShape:kCAEmitterLayerLine
                                           renderMode:kCAEmitterLayerAdditive];
        [self.layer addSublayer:_fireLayer];
        
        // 配置火花
        CAEmitterCell *fireCell = [CAEmitterCell emitterCell];
        fireCell.name = @"fireCell";
        fireCell.birthRate = 450.f;
        fireCell.scaleSpeed = 0.5;
        fireCell.lifetime = 0.9f;
        fireCell.lifetimeRange = 0.315;
        
        fireCell.velocity = -80.f;
        fireCell.velocityRange = 30;
        fireCell.yAcceleration = -200;
        
        fireCell.emissionLongitude = M_PI;
        fireCell.emissionRange = 1.1;
        
        fireCell.color = [[UIColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:0.1] CGColor];
        fireCell.contents = (id)[[UIImage imageNamed:@"fire_white"] CGImage];
        
        // 添加动画
        _fireLayer.emitterCells = @[fireCell];
    }
    return _fireLayer;
}

- (CAEmitterLayer *)smokeLayer {
    if (_smokeLayer == nil) {
        [self fireLayer];
        // 烟雾
        _smokeLayer = [self ZLEmitterLayerWithPosition:CGPointMake(self.bounds.size.width*0.5, self.bounds.size.height-60) size:CGSizeMake(0, 0) emitterMode:kCAEmitterLayerPoints emitterShape:nil renderMode:kCAEmitterLayerAdditive];
        [self.layer addSublayer:_smokeLayer];
        
        
        // 配置烟雾
        CAEmitterCell *smokeCell = [CAEmitterCell emitterCell];
        smokeCell.name = @"smokeCell";
        smokeCell.birthRate = 11.f;
        smokeCell.scale = 0.1;  // 缩放
        smokeCell.scaleSpeed = 0.7;
        smokeCell.lifetime = 3.6;
        
        smokeCell.velocity = -40.f;
        smokeCell.velocityRange = 20;
        smokeCell.yAcceleration = -160; // 向上
        
        smokeCell.emissionLongitude = -M_PI_2; // 向上
        smokeCell.emissionRange = M_PI * 0.25; // 围绕x轴方向成90度
        
        smokeCell.spin = 1; // 自旋转
        smokeCell.spinRange = 6;
        
        smokeCell.alphaSpeed = -0.12; // 透明度
        smokeCell.color = [[UIColor colorWithRed:1 green:1 blue:1 alpha:0.27] CGColor];
        smokeCell.contents = (id)[[UIImage imageNamed:@"smoke_white"] CGImage];
        
        _smokeLayer.emitterCells = @[smokeCell];
    }
    return _smokeLayer;
}

/**
 * 控制火花和烟雾的高度
 */
- (void)setFireAndSmokeHeight:(UIEvent *)event{
    // 获取手指所在点
    UITouch *touch = event.allTouches.anyObject;
    CGPoint touchpoint = [touch locationInView:self];
    
    // 计算比例
    CGFloat distanceToBottom = self.bounds.size.height - touchpoint.y;
    CGFloat per = distanceToBottom / self.bounds.size.height;
    
    // 设置数量
    [self setFireAndSmokeCount:2*per];
}

/**
 * 设置火花的数量
 */
- (void)setFireAndSmokeCount:(float)ratio{
    
    // 烟雾
    // 生命周期
    [self.smokeLayer setValue:@(ratio*4) forKeyPath:@"emitterCells.smokeCell.lifetime"];
    // 透明度
    [self.smokeLayer setValue:(id)[[UIColor colorWithRed:1 green:1 blue:1 alpha:ratio * 0.3] CGColor] forKeyPath:@"emitterCells.smokeCell.color"];
    
    
    // 火花
    // 产生数量
    [self.fireLayer setValue:@(ratio * 500.0) forKeyPath:@"emitterCells.fireCell.birthRate"];
    // 生命周期
    [self.fireLayer setValue:[NSNumber numberWithFloat:ratio] forKeyPath:@"emitterCells.fireCell.lifetime"];
    // 生命周期变化范围
    [self.fireLayer setValue:@(ratio * 0.35) forKeyPath:@"emitterCells.fireCell.lifetimeRange"];
    // 发射源大小
    [self.fireLayer setValue:[NSValue valueWithCGPoint:CGPointMake(ratio * 50, 0)] forKeyPath:@"emitterSize"];
    
}

#pragma mark - 烟花
- (CAEmitterLayer *)fireworksLayer {
    if (_fireworksLayer==nil) {
        
        // 配置layer
        CGPoint position = CGPointMake(self.layer.bounds.size.width * 0.5, self.layer.bounds.size.height); // 在底部
        CGSize size = CGSizeMake(self.layer.bounds.size.width * 0.1, 0.f);  // 宽度为一半
    
        _fireworksLayer = [self ZLEmitterLayerWithPosition:position
                                                                     size:size
                                                              emitterMode:kCAEmitterLayerOutline
                                                             emitterShape:kCAEmitterLayerLine
                                                               renderMode:kCAEmitterLayerAdditive];
        [self.layer addSublayer:_fireworksLayer];
        
        // 发射
        // 上一个销毁了，下一个才发出来
        CAEmitterCell *shootCell = [self ZLEmitterCellContents:(id)[[UIImage imageNamed:@"shoot_white"] CGImage]
                                                     birthRate:1.0f lifetime:1.02
                                                      velocity:500.f
                                                         scale:0.05];
       
        [CAEmitterCell emitterCell];
        
        shootCell.name = @"shootCell";
        
        shootCell.velocityRange = 100.f;
        shootCell.yAcceleration = 75.0f; // 模拟重力
        
        shootCell.emissionRange = M_PI * 0.25;
        
        shootCell.color = UIColor.redColor.CGColor;
        shootCell.greenRange = 1.f;
        shootCell.redRange = 1.f;
        shootCell.blueRange = 1.f;
        
        
        shootCell.spinRange = 2*M_PI; // 自转360度
        
        // 爆炸
        CAEmitterCell *explodeCell = [CAEmitterCell emitterCell];
        explodeCell.name = @"explodeCell";
        explodeCell.birthRate = 1.f;
        explodeCell.lifetime = 0.2f;
        explodeCell.velocity = .0f;
        explodeCell.scale = 2.5;
        explodeCell.redSpeed = -1.5; //爆炸的时候变化颜色
        explodeCell.blueRange = 1.5;
        explodeCell.greenRange = 1.f;
        
        // 火花
        CAEmitterCell *sparkCell = [CAEmitterCell emitterCell];
        sparkCell.name = @"sparkCell";
        sparkCell.birthRate = 800.f;
        sparkCell.lifetime = 3.f;
        sparkCell.velocity = 125.f;
        sparkCell.yAcceleration = 75.f;  // 模拟重力影响
        sparkCell.emissionRange = M_PI * 2;  // 360度
        
        sparkCell.scale = 1.2f;
        sparkCell.contents = (id)[[UIImage imageNamed:@"star_white_stroke"] CGImage];
        sparkCell.redSpeed = 0.4;
        sparkCell.greenSpeed = -0.1;
        sparkCell.blueSpeed = -0.1;
        sparkCell.alphaSpeed = -0.25;
        
        sparkCell.spin = M_PI * 2; // 自转
        
        // 添加动画
        _fireworksLayer.emitterCells = @[shootCell];
        shootCell.emitterCells = @[explodeCell];
        explodeCell.emitterCells = @[sparkCell];
    }
    return _fireworksLayer;
}

#pragma mark - Commons
// 配置粒子发射器
- (CAEmitterLayer *)ZLEmitterLayerWithPosition:(CGPoint)position
                                          size:(CGSize)size
                                   emitterMode:(NSString *)emitterMode
                                  emitterShape:(NSString *)emitterShape
                                    renderMode:(NSString *)renderMode {

    CAEmitterLayer * aEmitterLayer = [CAEmitterLayer layer];
    // 发射源的位置
    aEmitterLayer.emitterPosition = position;
    // 发射源size，决定了发射源的大小
    aEmitterLayer.emitterSize = size;
    // 发射模式
    aEmitterLayer.emitterMode = emitterMode;
    // 发射器的形状
    aEmitterLayer.emitterShape = emitterShape;
    // 渲染模式
    aEmitterLayer.renderMode = renderMode;

    return aEmitterLayer;
}
// 配置cell
- (CAEmitterCell *)ZLEmitterCellContents:(nullable id)contents
                       birthRate:(float)rate lifetime:(float)lifetime
                        velocity:(CGFloat)velocity
                           scale:(CGFloat)scale {
    
    CAEmitterCell *aCell = [CAEmitterCell emitterCell];
    // 粒子内容
    aCell.contents = contents;
    // 每秒产生粒子数量
    aCell.birthRate = rate;
    // 粒子生命周期
    aCell.lifetime = lifetime;
    
    // 粒子的速度
    aCell.velocity = velocity;
    // 粒子在y方向的加速度
//    aCell.yAcceleration = 1000.;
    
    // 粒子缩放比例
    aCell.scale = scale;
    
    return aCell;
}

#pragma mark - Actions
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if (_smokeLayer || _fireLayer) {
        [self setFireAndSmokeHeight:event];
    }
    if (_colorBallLayer) {
        UITouch * touch = [[event allTouches] anyObject];
        [self setBallInPsition:[touch locationInView:self]];
    }
    if (_heartLayer) {
        // 添加动画
        CABasicAnimation * heartAnim = [CABasicAnimation animationWithKeyPath:@"emitterCells.heartCell.birthRate"];
        heartAnim.fromValue = @30.f;
        heartAnim.toValue = @0.f;
        heartAnim.duration = 5.f;
        heartAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
        [self.heartLayer addAnimation:heartAnim forKey:@"heartAnim"];
    }
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    if (_smokeLayer || _fireLayer) {
        [self setFireAndSmokeHeight:event];
    }
    if (_colorBallLayer) {
        UITouch * touch = [[event allTouches] anyObject];
        [self setBallInPsition:[touch locationInView:self]];
    }
}


#pragma mark - xxxxx
/** 燃烧的火焰 */
- (void)fireago {
    
    self.backgroundColor = UIColor.blackColor;
    
    CAEmitterLayer *fireEmitter = [[CAEmitterLayer alloc] init];
    fireEmitter.emitterPosition = self.center;
    // 发射器的尺寸大小
    //    fireEmitter.emitterSize = CGSizeMake(20, 60);
    // 发射器的发射模式
    //        fireEmitter.emitterMode = kCAEmitterLayerOutline
    // 发射器的形状
    fireEmitter.emitterShape = kCAEmitterLayerCircle;
    // 发射器渲染模式
    fireEmitter.renderMode = kCAEmitterLayerAdditive;
    
    CAEmitterCell *emittercell = [[CAEmitterCell alloc] init];
    // 粒子的创建速率，默认为1/s。
    emittercell.birthRate = 200;
    // 粒子存活时间
    emittercell.lifetime = 0.2;
    // 粒子的生存时间容差
    emittercell.lifetimeRange = 0.5;
    emittercell.color = [UIColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:0.1].CGColor;
    emittercell.contents = (__bridge id)[UIImage imageNamed:@"DazFire"].CGImage;
    emittercell.name = @"fire";
    // 粒子的速度
    emittercell.velocity = 35;
    // 粒子动画的速度容差
    emittercell.velocityRange = 10;
    // 粒子在xy平面的发射角度
    emittercell.emissionLongitude= (CGFloat)(M_PI + M_PI_2);
    // 粒子发射角度的容差
    emittercell.emissionRange = (CGFloat)M_PI_2;
    // 缩放速度
    emittercell.scaleSpeed = 0.3;
    // 旋转度
    //        emittercell.spin = 0.2;
    
    fireEmitter.emitterCells = @[emittercell];
    [self.layer addSublayer:fireEmitter];
}



@end
